package client;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.cert.X509Certificate;
import java.util.Scanner;

import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

public class Connection {
	private SSLSocket socket;
	private ObjectInputStream ois;
	private ObjectOutputStream oos;
	

	public boolean connect(String host) {
		int port = 34567;
		
		System.out.println("Connecting to " + host + ":" + port);
		try {
			// Set up streams
			socket = (SSLSocket)SSLSocketFactory.getDefault().createSocket(host, port);
			ois = new ObjectInputStream(socket.getInputStream());
			oos = new ObjectOutputStream(socket.getOutputStream());
			
			// Authenticate server
			SSLSession session = socket.getSession();
			X509Certificate serverCert = (X509Certificate)session.getPeerCertificates()[0];		
			Scanner sc = new Scanner(serverCert.getSubjectX500Principal().getName("RFC1779")).useDelimiter(",");
			String uname = sc.next().trim();
			if (!uname.startsWith("CN=") || uname.length() <= 3) {
				throw new SSLPeerUnverifiedException("Couldn't parse CN from user cert.");
			}
			if(!uname.equals("CN=Server-Snild")){
				throw new IOException("Server is a smurf");
			}
			
			System.out.println("Connection message: "+ois.readUTF());
			System.out.println("Connected");
			return true;		
		} catch (IOException e) {
			System.out.println("Connection failed: "+ e.getMessage());
		}
		
		return false;
	}
	
	public void disconnect(){
		try {
			oos.close();
			ois.close();
			socket.close();
		} catch (IOException e) {
			// TODO : Failed at disconnecting, what do?
		}
	}
	
	public Response getList()  {
		send("list");
		return receive();
	}

	public Response viewJournal(int id)  {
		send("get");
		send(id);
		return receive();
	}


	public Response setJournalContent(int id,String journal)  {
		send("set");
		send(id);
		send(journal);
		return receive();
	}

	public Response createJournal(String patient, String nurse)  {
		send("create");
		send(patient);
		send(nurse);
		return receive();
	}

	public Response deleteJournal(int id)  {
		send("delete");
		send(id);
		return receive();
	}	
	
	private void send(String message){
		try {
			oos.writeUTF(message);
			oos.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private void send(int message){
		try {
			oos.writeInt(message);
			oos.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private Response receive()  {
		try {
			int status = ois.readInt();
			String msg = ois.readUTF();
			return new Response(status, msg);
		} catch (IOException e) {
			return new Response(-1, "Communication error.");
		}
	}
}

